﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;


namespace TaskBasedSchedule.Core
{
    public sealed class Framework
    {
        #region Constants

        private static readonly string USER_CONTEXT_IDENTITY = "UC_000001";

        #endregion

        #region Singleton
        private static Framework _instance;

        static Framework()
        {
            _instance = new Framework();
        }

        public static Framework Instance
        {
            get
            {
                return _instance;
            }
        }

        #endregion

        #region Fields

        private readonly object _syncLocker = new object();

        private Dictionary<string, UserContext> _signInAccountTable;

        #endregion

        #region Constructor&Destructor

        private Framework()
        {
            PrivateInitialize();
        }

        #endregion

        #region Properties

        public Accounts Accounts
        {
            get
            {
                throw new System.NotImplementedException();
            }

            set
            {
            }
        }

        public UserContext CurrentContext
        {
            get
            {
                throw new System.NotImplementedException();
            }

            set
            {
            }
        }

        public DatabaseFactory Database { get; private set; }

        public Authorities Authorities { get; private set; }

        #endregion

        #region Private Functions

        private UserContext PrivateGetCurrentContext()
        {
            var context = HttpContext.Current;

            if (context == null)
            {
                //The client thread doesn't have a http context.
                return null;
            }

            if (context.Session[USER_CONTEXT_IDENTITY] != null)
            {
                return context.Session[USER_CONTEXT_IDENTITY] as UserContext;
            }else
            {
                context.Session[USER_CONTEXT_IDENTITY] = PrivateCreateContext();
                
                return context.Session[USER_CONTEXT_IDENTITY] as UserContext;
            }
        }

        private UserContext PrivateCreateContext()
        {
            throw new System.NotImplementedException();
        }

        private void PrivateInitialize()
        {
            _signInAccountTable = new Dictionary<string, UserContext>();

            //Database is the first thing we need to initialize.
            //Cause all the manangers initialized below require Database Support.
            Database = new DatabaseFactory();

            Authorities = new Authorities();
        }

        #endregion

        #region Internal Functions

        internal void InternalAcquireAccountSlot(UserContext context, string account)
        {
            UserContext loser = null;

            lock (_syncLocker)
            {
                if (_signInAccountTable.ContainsKey(account))
                {
                    loser = _signInAccountTable[account];
                    _signInAccountTable[account] = context;
                }
                else
                {
                    _signInAccountTable.Add(account, context);
                }
            }

            if (loser != null)
                loser.SignOut(SignOutReason.Conflict);
        }

        internal void InternalFreeAccountSlot(string account)
        {
            lock (_syncLocker)
            {
                if (_signInAccountTable.ContainsKey(account))
                {
                    _signInAccountTable.Remove(account);
                }
            }
        }

        #endregion
    }
}